#include <stdlib.h>
#include <stdio.h>

#define private static
#define public

#define RECORD_COUNT 4

#define FILE_NAME "work.txt"
#define INPUT_FILE_NAME FILE_NAME
#define OUTPUT_FILE_NAME FILE_NAME

typedef FILE *File;

/* 职员对象 */

typedef struct _Employee {
  char name[8];
  int age;
  int salary;
} *Employee;

public void employee_free(Employee employee) {
  free(employee);
}

public Employee employee_read(File istream) {
  Employee employee = (Employee) calloc(1, sizeof(struct _Employee));
  if (employee == NULL) {
    fprintf(stderr, "employee_read: out of memory\n");
    exit(EXIT_FAILURE);
  }
  if (fscanf(istream, "%s%d%d", employee->name, &employee->age, &employee->salary) != 3) {
    employee_free(employee);
    return NULL;
  }
  return employee;
}

public void employee_print(Employee employee, File ostream) {
  fprintf(ostream, "%s %d %d\n", employee->name, employee->age, employee->salary);
}

public void employee_adjust_salary(Employee employee) {
  if (employee->salary < 30000) {
    employee->salary += 3000;
  }
}

/* 应用层 */

int main(void) {
  Employee employees[RECORD_COUNT];

  /* 从文件读入 */
  File istream = fopen(INPUT_FILE_NAME, "r");
  if (istream == NULL) {
    fprintf(stderr, "Cannot open %s with r mode.\n", INPUT_FILE_NAME);
    exit(EXIT_FAILURE);
  }
  for (int index = 0; index < RECORD_COUNT; index++) {
    employees[index] = employee_read(istream);
  }
  fclose(istream);

  /* 1. 输出到屏幕 */
  for (int index = 0; index < RECORD_COUNT; index++) {
    employee_print(employees[index], stdout);
  }

  /* 2. 调整薪资 */
  for (int index = 0; index < RECORD_COUNT; index++) {
    employee_adjust_salary(employees[index]);
  }

  /* 3. 输出调整后的结果 */
  for (int index = 0; index < RECORD_COUNT; index++) {
    employee_print(employees[index], stdout);
  }

  /* 4. 保存到文件 */
  File ostream = fopen(OUTPUT_FILE_NAME, "w");
  if (ostream == NULL) {
    fprintf(stderr, "Cannot open %s with w mode.\n", OUTPUT_FILE_NAME);
    exit(EXIT_FAILURE);
  }
  for (int index = 0; index < RECORD_COUNT; index++) {
    employee_print(employees[index], ostream);
  }
  fclose(ostream);

  /* 释放资源 */
  for (int index = 0; index < RECORD_COUNT; index++) {
    employee_free(employees[index]);
  }

  return EXIT_SUCCESS;
}
